package com.blog.service;

import com.blog.dao.BlogDAO;
import com.blog.dao.TypeDAO;
import com.blog.dao.UserDAO;

import com.blog.domain.Blog;
import com.blog.domain.Type;
import com.blog.domain.User;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for User entities
 * 
 */

@Service("UserService")
@Transactional
public class UserServiceImpl implements UserService {

	/**
	 * DAO injected by Spring that manages Blog entities
	 * 
	 */
	@Autowired
	private BlogDAO blogDAO;

	/**
	 * DAO injected by Spring that manages Type entities
	 * 
	 */
	@Autowired
	private TypeDAO typeDAO;

	/**
	 * DAO injected by Spring that manages User entities
	 * 
	 */
	@Autowired
	private UserDAO userDAO;

	/**
	 * Instantiates a new UserServiceImpl.
	 *
	 */
	public UserServiceImpl() {
	}

	/**
	 * Return all User entity
	 * 
	 */
	@Transactional
	public List<User> findAllUsers(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<User>(userDAO.findAllUsers(startResult, maxRows));
	}

	/**
	 * Save an existing User entity
	 * 
	 */
	@Transactional
	public void saveUser(User user) {
		User existingUser = userDAO.findUserByPrimaryKey(user.getId());

		if (existingUser != null) {
			if (existingUser != user) {
				existingUser.setId(user.getId());
				existingUser.setUsername(user.getUsername());
				existingUser.setPassword(user.getPassword());
				existingUser.setNickName(user.getNickName());
				existingUser.setSex(user.getSex());
				existingUser.setRegister(user.getRegister());
				existingUser.setImage(user.getImage());
			}
			user = userDAO.store(existingUser);
		} else {
			user = userDAO.store(user);
		}
		userDAO.flush();
	}

	/**
	 * Return a count of all User entity
	 * 
	 */
	@Transactional
	public Integer countUsers() {
		return ((Long) userDAO.createQuerySingleResult("select count(o) from User o").getSingleResult()).intValue();
	}

	/**
	 */
	@Transactional
	public User findUserByPrimaryKey(Integer id) {
		return userDAO.findUserByPrimaryKey(id);
	}

	/**
	 * Delete an existing Blog entity
	 * 
	 */
	@Transactional
	public User deleteUserBlogs(Integer user_id, Integer related_blogs_id) {
		Blog related_blogs = blogDAO.findBlogByPrimaryKey(related_blogs_id, -1, -1);

		User user = userDAO.findUserByPrimaryKey(user_id, -1, -1);

		related_blogs.setUser(null);
		user.getBlogs().remove(related_blogs);

		blogDAO.remove(related_blogs);
		blogDAO.flush();

		return user;
	}

	/**
	 * Delete an existing User entity
	 * 
	 */
	@Transactional
	public void deleteUser(User user) {
		userDAO.remove(user);
		userDAO.flush();
	}

	/**
	 * Save an existing Blog entity
	 * 
	 */
	@Transactional
	public User saveUserBlogs(Integer id, Blog related_blogs) {
		User user = userDAO.findUserByPrimaryKey(id, -1, -1);
		Blog existingblogs = blogDAO.findBlogByPrimaryKey(related_blogs.getId());

		// copy into the existing record to preserve existing relationships
		if (existingblogs != null) {
			existingblogs.setId(related_blogs.getId());
			existingblogs.setTitle(related_blogs.getTitle());
			existingblogs.setContent(related_blogs.getContent());
			existingblogs.setDate(related_blogs.getDate());
			existingblogs.setReader(related_blogs.getReader());
			related_blogs = existingblogs;
		} else {
			related_blogs = blogDAO.store(related_blogs);
			blogDAO.flush();
		}

		related_blogs.setUser(user);
		user.getBlogs().add(related_blogs);
		related_blogs = blogDAO.store(related_blogs);
		blogDAO.flush();

		user = userDAO.store(user);
		userDAO.flush();

		return user;
	}

	/**
	 * Load an existing User entity
	 * 
	 */
	@Transactional
	public Set<User> loadUsers() {
		return userDAO.findAllUsers();
	}

	/**
	 * Delete an existing Type entity
	 * 
	 */
	@Transactional
	public User deleteUserTypes(Integer user_id, Integer related_types_id) {
		Type related_types = typeDAO.findTypeByPrimaryKey(related_types_id, -1, -1);

		User user = userDAO.findUserByPrimaryKey(user_id, -1, -1);

		related_types.setUser(null);
		user.getTypes().remove(related_types);

		typeDAO.remove(related_types);
		typeDAO.flush();

		return user;
	}

	/**
	 * Save an existing Type entity
	 * 
	 */
	@Transactional
	public User saveUserTypes(Integer id, Type related_types) {
		User user = userDAO.findUserByPrimaryKey(id, -1, -1);
		Type existingtypes = typeDAO.findTypeByPrimaryKey(related_types.getId());

		// copy into the existing record to preserve existing relationships
		if (existingtypes != null) {
			existingtypes.setId(related_types.getId());
			existingtypes.setName(related_types.getName());
			related_types = existingtypes;
		} else {
			related_types = typeDAO.store(related_types);
			typeDAO.flush();
		}

		related_types.setUser(user);
		user.getTypes().add(related_types);
		related_types = typeDAO.store(related_types);
		typeDAO.flush();

		user = userDAO.store(user);
		userDAO.flush();

		return user;
	}
}
